package cn.edu.cug.cs.gtl.docsrv.img.service.impl;


import cn.edu.cug.cs.gtl.docsrv.dict.exception.BaseException;
import cn.edu.cug.cs.gtl.docsrv.img.dao.ImgDao;
import cn.edu.cug.cs.gtl.docsrv.img.service.ImgService;
import cn.edu.cug.cs.gtl.docsrv.img.catalog.CatalogTree; 
import cn.edu.cug.cs.gtl.io.FileDataSplitter;
import cn.edu.cug.cs.gtl.mybatis.mapper.img.ImgAll;
import cn.edu.cug.cs.gtl.mybatis.mapper.img.ImgItem;

import cn.edu.cug.cs.gtl.mybatis.mapper.img.ImgAll;
import cn.edu.cug.cs.gtl.mybatis.mapper.img.ImgCatalog;
import cn.edu.cug.cs.gtl.mybatis.metadata.ImgUtils;
import cn.edu.cug.cs.gtl.protos.Document;
import cn.edu.cug.cs.gtl.protos.DocumentList;
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.GeometryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.List;

@Component
public class ImgServiceImpl implements ImgService {


    @Autowired
    ImgDao imgDao;

    public ImgServiceImpl(){super();}

    /** 
     * 服务名称：addImg
     * 功能描述：单个本地Img文件入库
     * 接口描述： /api/img/addImg
     * 传入参数：
     * ImgAll  img；前端传入ImgAll的JSON对象
     * 返回值：
     * 成功返回true , 否则返回false
     * 调用示例：
     *
     * @param imgAll
     */
    @Override
    public void addImg(ImgAll imgAll) {
        imgDao.addImg(imgAll);
    }

    /** 
     * 服务名称：addImgs
     * 功能描述：多个本地SHP文件入库
     * 接口描述： /api/img/ addImgs
     * 传入参数：
     * List<ImgAll>  imgs；前端传入ImgAll列表的JSON对象
     * 返回值：
     * 成功返回true , 否则返回false
     * 调用示例：
     *
     * @param ls
     */
    @Override
    public void addImgs(List<ImgAll> ls) {
        imgDao.addImgs(ls);
    }

    /** 
     * 服务名称：addFromRawDB
     * 功能描述：从原始数据库中提取指定类型的图像文件入库
     * 接口描述： /api/img/addFromRawDB
     * 传入参数：
     * String imgType   图像类型，文件后缀；
     * 返回值：
     * 成功返回true , 否则返回false
     * 调用示例：
     */
    @Deprecated
    @Override
    public boolean addFromRawDB() {
        return imgDao.addFromRawDB();
    }

    /**
     * 服务名称：getImgByName
     * 功能描述：图像数据库中提取指定名称的图像文件
     * 接口描述： /api/img/getImgByName
     * 传入参数：
     * String imgName   图像名称；
     * 返回值：
     * List<ImgAll> imgAllList 的JSON字符串
     * 调用示例：
     *
     * @param imgName
     */
    @Override
    public List<ImgAll> getImgByName(String imgName) {
        return imgDao.getImgByName(imgName);
    }

    /**
     * 服务名称：getImgByEnTitle
     * 功能描述：图像数据库中提取指定英文名称的图像文件
     * 接口描述： /api/img/ getImgByEnTitle
     * 传入参数：
     * String enTitle ；
     * 返回值：
     * List<ImgAll> imgAllList 的JSON字符串
     * 调用示例：
     *
     * @param enTitle
     */
    @Override
    public List<ImgAll> getImgByEnTitle(String enTitle) {
        return imgDao.getImgByEnTitle(enTitle);
    }

    /**
     * 服务名称：getImgByCnTitle
     * 功能描述：图像数据库中提取指定中文名称的图像文件
     * 接口描述： /api/img/ getImgByCnTitle
     * 传入参数：
     * String cnTitle ；
     * 返回值：
     * List<ImgAll> imgAllList 的JSON字符串
     * 调用示例：
     *
     * @param cnTitle
     */
    @Override
    public List<ImgAll> getImgByCnTitle(String cnTitle) {
        return imgDao.getImgByCnTitle(cnTitle);
    }

    /**
     * 服务名称：getImgByInternalId
     * 功能描述：图像数据库中提取指定ID的图像文件
     * 接口描述： /api/img/getImgByInternalId
     * 传入参数：
     * long internalId；
     * 返回值：
     * ImgAll  img     ; ImgAll的JSON字符串
     * 调用示例：
     *
     * @param internalId
     */
    @Override
    public ImgAll getImgByInternalId(BigDecimal internalId) {
        return imgDao.getImgByInternalId(internalId);
    }

    /**
     * 服务名称：getImgByBoundingBox
     * 功能描述：图像数据库中提取指定范围的图像
     * 接口描述： /api/img/getImgByBoundingBox
     * 传入参数：
     * String bb；//minx,maxx,miny,maxy  数字之间逗号分隔
     * String mask; //intersect 相交的图像； 或  contains 包含的图像
     * 返回值：
     * List<ImgAll> imgAllList 的JSON字符串
     * 调用示例：
     *
     * @param bb
     * @param mask
     */
    @Override
    public List<ImgAll> getImgByBoundingBox(String bb, String mask) {
        if(bb==null || bb.length()<4) return null;
        String [] cs = bb.split(FileDataSplitter.COMMA.getDelimiter());
        double minX = Double.valueOf(cs[0]).doubleValue();
        double maxX = Double.valueOf(cs[1]).doubleValue();
        double minY = Double.valueOf(cs[2]).doubleValue();
        double maxY = Double.valueOf(cs[3]).doubleValue();
        Envelope envelope = new Envelope(minX,maxX,minY,maxY);
        GeometryFactory gf = new GeometryFactory();
        return imgDao.getImgByBoundingBox(gf.toGeometry(envelope),mask);
    }

    /**
     * 服务名称：deleteImgByInternalId
     * 功能描述：删除图像数据库中指定ID的图像
     * 接口描述： /api/img/deleteImgByInternalId
     * 传入参数：
     * long internalId；
     * 返回值：
     * 成功返回true , 否则返回false
     * 调用示例：
     *
     * @param internalId
     */
    @Override
    public boolean deleteImgByInternalId(BigDecimal internalId) {
        return imgDao.deleteImgByInternalId(internalId);
    }

    /**
     * 服务名称：getImagesByImgInternalId
     * 功能描述：图像数据库中提取指定Img的几何对象
     * 接口描述： /api/img/getImagesByImgInternalId
     * 传入参数：
     * long imgInternalId
     * 返回值：
     * IamgeJSON的列表
     * 调用示例：
     *
     * @param imgInternalId
     */
    @Override
    public List<String> getImagesByImgInternalId(BigDecimal imgInternalId) {
        return null;
    }

    /**
     * 服务名称：getEnvelopeByImgInternalId
     * 功能描述：图像数据库中提取指定范围的几何对象
     * 接口描述： /api/img/getEnvelopeByImgInternalId
     * 传入参数：
     * long imgInternalId
     * 返回值：
     * Envelope
     * 调用示例：
     *
     * @param imgInternalId
     */
    @Override
    public Envelope getEnvelopeByImgInternalId(BigDecimal imgInternalId) {
        return imgDao.getEnvelopeByImgInternalId(imgInternalId);
    }

    /**
     * 服务名称：getImgCatalogs
     * 功能描述：图像数据库中提取所有分类
     * 接口描述： /api/img/getImgCatalogs
     * 传入参数：
     * 返回值：
     * List<ImgCatalog> catalogs
     * 调用示例：
     */
    @Override
    public List<ImgCatalog> getImgCatalogs() {
        return imgDao.getImgCatalogs();
    }

    /**
     服务名称：getDocumentByImgInternalId
     功能描述：图像数据库中提取指定Img文档
     接口描述： /api/img/getDocumentByImgInternalId
     传入参数：
     long imgInternalId
     返回值：
     Document doc;
     其中，每个Feature的GeoJSON字符串为Document的一个content；
     其他的不为空的字段为该Img文档的元数据。
     调用示例：
     http://localhost:8090/api/img/getDocumentByImgInternalId?imgInternalId=3
     */
    @Override
    public Document getDocumentByImgInternalId(BigDecimal imgInternalId){
        try {
            return   imgDao.getDocumentByImgInternalId(imgInternalId);
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }

    /**
     * 服务名称：getDocumentsByCatalogInternalId
     * 功能描述：图像数据库中提取指定分类ID的所有图像文档
     * 接口描述：/api/img/getDocumentsByCatalogInternalId
     * 传入参数：
     * long catalogInternalId
     * 返回值：
     * DocumentList docList;
     * 其中，每个Feature的GeoJSON字符串为Document的一个content；
     * 其他的不为空的字段为该Img文档的元数据。
     * 调用示例：
     * http://localhost:8090/api/img/getDocumentsByCatalogInternalId?catalogInternalId=3
     *
     * @param catalogInternalId
     */
    @Override
    public DocumentList getDocumentsByCatalogInternalId(BigDecimal catalogInternalId) {
        try {
            try {
                List<ImgAll> imgAllList= imgDao.getImgByCatalogInternalId(catalogInternalId);
                if(imgAllList!=null) {
                    DocumentList.Builder documentListBuilder = DocumentList.newBuilder();
                    for (ImgAll imgAll : imgAllList) {
                        Document doc = ImgUtils.convert(imgAll);
                        documentListBuilder.addElement(doc);
                    }
                    return documentListBuilder.build();
                }
                else
                    return null;
            } catch (Exception e) {
                throw new BaseException(e.getMessage());
            }
        } catch (Exception e) {
            throw new BaseException(e.getMessage());
        }
    }

    /**
     * 将所有的目录整理成一个树后返回
     *
     * @return
     */
    @Override
    public CatalogTree getCatalogTree() {
        return imgDao.getCatalogTree();
    }

    @Override
    public List<BigDecimal> getImgInternalIdsByCatalogInternalId(BigDecimal catalogId) {
        return imgDao.getImgInternalIdsByCatalogInternalId(catalogId);
    }
}
